package global

import (
	"sync"
	log "code.google.com/p/log4go"
	"encoding/json"
	"github.com/toolkits/file"
	"errors"
	"fmt"
)

/**
   mysql相关配置
 */
type MysqlConfig struct {
	Ip string `json:"ip"`
	Port string `json:"port"`
	CharacterEncoding string `json:"characterEncoding"`
}
/**
   hbase 相关配置
 */
type HbaseConfig struct {
	Ip string `json:"ip"`
}

/**
	RowKey的相关配置
 */
type KeyParameter struct {
	Key string `json:"key"` //在RowKey里面配置的字段列表之一
	IsReverse bool `json:"is_reverse"` //字段是否需要反转，默认是false
	IsTime bool `json:"is_time"` //是否是时间字段，如果是，则会去除 "-" " " ":" 横杠，空格，例如：冒号等字符 2017-12-12 12:12:12 最后会成为20171212121212
	Length int `json:"length"` //如果此值>0，则，如果字段不够length，会在其左侧补0
}
/**
	任务配置
 */
type Task struct {
	TaskName string `json:"taskName"`
	TaskCommond string `json:"taskCommond"`
	Speed int64 `json:"speed"` //程序休眠时长，单位毫秒,流式任务，或者定时任务流式执行，配置上一个轮次执行完休眠多少秒，继续下一轮执行。这个是对此类型的任务进行限速
	IsUse bool `json:"isUse"`
	OnlyDelete bool `json:"onlyDelete"`
	UserName string `json:"username"`
	Password string `json:"password"`
	Database string `json:"database"`
	Table string `json:"table"`
	MaxOpenConns int `json:"maxOpenConns"`
	MaxIdleConns int `json:"maxIdleConns"`
	Key string `json:"key"`
	Condition string `json:"condition"`
	Parameter []string `json:"parameter"`
	Cron string `json:"cron"`
	IsFlow bool `json:"isFlow"` //定时任务是否是流式定时，默认是false,如果配置了true，则触发了只要能查询到数据就会一直执行。
	Limit int `json:"limit"`
	Delete bool `json:"delete"`
	SyncColumn string `json:"sync_column"` //当只是同步数据到Hbase，并不删除源数据，需要提供一个标示是否已经同步的字段
	SyncValue string `json:"sync_value"`//当只是同步数据到Hbase，并不删除源数据，则同步成功后，将sync_column对应的字段改为sync_value
	HbaseTable string `json:"hbase_table"`//Hbase表名，不配置使用mysql的表名
	Separator string `json:"separator"`//分割符，作为hbase rowkey多个字段的分割符
	RowKey string `json:"row_key"` //rowkey的多个字段，多个使用,号分割
	KeyParam []*KeyParameter `json:"key_parameter"` //rowKey相关的参数设置
	PartOf bool `json:"part_of"`//是否允许只导入部分的列到Hbase中
	ToLower bool `json:"toLower"`//存储到Hbase时，列名是否全部转小写
	ToUpper bool `json:"toUpper"`//存储到Hbase时，列名是否全部转大写
	CloumnFamily []map[string][]string `json:"column_family"`
}
/**
	全局配置
 */
type ConfigGlobal struct {
	Namespace string `json:"namespace"` //命名空间，一个服务一个命名空间
	LogLevel string  `json:"logLevel"`
	Mysql *MysqlConfig `json:"mysql"`
	Hbase *HbaseConfig `json:"hbase"`
	Zookeeper string `json:"zookeeper"` //zookeeper命名空间，当此值不为Null时，表示该工作需要上Zk控制台，否则，代表无需zk，纯本地服务
	Tasks []*Task `json:"tasks"`
}
/**
	全局变量
 */
var (
	ConfigFile string
	config     *ConfigGlobal
	configLock = new(sync.RWMutex)
)
/**
	获取配置
 */
func Config() *ConfigGlobal {
	configLock.RLock()
	defer configLock.RUnlock()
	return config
}
/**
	解析配置
 */
func ParseConfig(cfg string) {
	if cfg == "" {
		errStr := fmt.Sprintf("use -c to-hbase specify configuration file")
		log.Info(errStr)
		PanicError(errors.New(errStr),nil)
	}
	if !file.IsExist(cfg) {
		errStr := fmt.Sprintf("config file: %s is not existent",cfg)
		log.Info(errStr)
		PanicError(errors.New(errStr),nil)
	}
	ConfigFile = cfg
	configContent, err := file.ToTrimString(cfg)
	if err != nil {
		errStr := fmt.Sprintf("read config file: %s fail: %s",cfg,err)
		log.Info(errStr)
		PanicError(errors.New(errStr),nil)
	}
	var c ConfigGlobal
	err = json.Unmarshal([]byte(configContent), &c)
	if err != nil {
		errStr := fmt.Sprintf("parse config file: %s fail: %s",cfg, err)
		log.Info(errStr)
		PanicError(errors.New(errStr),nil)
	}
	configLock.Lock()
	defer configLock.Unlock()
	config = &c
	log.Info("read config file: %s successfully",cfg)
}